Introduction#

APIs provide services by exchanging information between client and server processes. The underlying network stack usually abstracts this interprocess communication, but how is it done? Popular API technologies such as RESTful, GraphQL, and gRPC work differently, but at the most basic level, they all use socket interfaces for process identification, connection establishment, and interprocess communication.

Let’s see the basic requirements for successful communication between two processes or services that operate on separate networked devices:

  • Identification of devices on the internet.

  • Identification of processes on the communicating devices.

  • Steps or procedures to exchange data between those processes.

Let’s understand how sockets play an important role in maintaining these three requirements.

What is a socket?#

A socket is an interface that creates a two-way channel between processes communicating on different devices. Processes running on the application layer use sockets as an interface to take services from the transport layer to establish communication. Further, the interfacing requires an IP address and a port number to uniquely identify a process or application globally. The interface (IP address + port) is referred to as a socket address.

Two different sockets (endpoints) are required for any two processes to communicate. Each process in a connection is recognized by its respective socket address. The diagram below shows how “Process A" from a machine with "IP 1" can communicate with the “Process Y" on another machine with "IP 2."

Process A on device 1 wants to connect to Process Y on device 2
Process A on device 1 wants to connect to Process Y on device 2

Note: The ports used to run services on different devices can be different or the same. We can also assign the same port to different services on different devices connected to the internet. Port numbers ranging between 1–1024 are well-known ports because they’re mostly used as a standard for a particular service. For example, port 80 and 443 are used for HTTP and HTTPS, respectively.

Finally, the transport protocol (TCP or UDP) specified in the transport layer of the network stack is responsible for successfully exchanging data between these processes. All this information is present in the network stack, and we can access it using a single interface from the network socket.

The term socket was first coined in the early 1970s in RFC 147. Later, it materialized in 1983 at the University of California, Berkeley, in UNIX operating systems for interprocess communication. Thereafter, socket was adopted by developers around the world and became the de facto internet communication standard because it provides an efficient mechanism to identify processes running on the same machine and different machines.

Multiple concurrent connections#

Sockets enable the simultaneous creation of multiple communication channels on a single machine. The diagram below shows an example of multiple processes/services running on one machine (in this case, with an IP address of 104.18.2.119) and communicating with different processes running on different machines that are connected via a network in the following way:

  • SMTP service with socket 104.18.2.119:587 talking to socket 10.1.y.z:50625

  • HTTPS service with socket 104.18.2.119:443 talking to socket 10.2.y.z:54043

  • FTP service with socket 104.18.2.119:21 talking to socket 10.3.y.z:52134

  • PostgreSQL service with socket 104.18.2.119:5432 talking to socket 10.4.y.z:56432

The IP address 10.x.y.z used above is a private address range and is for illustration purposes only.

IP: 10.1.y.z
Port: 50625
Sending email
IP: 10.1.y.zPo...
SMTP: 587
SMTP: 587
IP: 10.2.y.z
Port: 54043
Browsing website
IP: 10.2.y.zPort: 54...
HTTPS: 443
HTTPS: 443
IP: 104.18.2.119
Serving different requests on different ports
IP: 104.18.2.119Serving d...
IP: 10.3.y.z
Port: 52134
Uploading media
IP: 10.3.y.zPort: 52...
IP: 10.4.y.z
Port: 56432
Requesting database
IP: 10.4.y.zPort: 56...
FTP: 21
FTP: 21
PostgreSQL: 5432
PostgreSQL: 5432
Viewer does not support full SVG 1.1
Identifying each device and service uniquely

Point to Ponder

Question

What is the maximum number of possible connections that can be established simultaneously on one machine?

Hide Answer

Because the size of the port number is 16 bits, the maximum number of ports on a machine is limited to 65,536. However, the answer to this question is tricky. The 5-tuple information on a machine that identifies a typical connection is as follows:

  • Source IP
  • Source port
  • Destination IP
  • Destination port
  • Transport layer protocol

Any combination of the information above can increase the maximum number. For example, a machine may have multiple IPs so that it can open more connections. Typically, both the available memory and computing power limit the number of simultaneous connections a machine can handle.

Categories of network sockets#

Network sockets can be categorized into two general types based on the transport protocol.

Stream sockets#

A stream socket creates a reliable end-to-end connection between the two endpoints using transport protocols like TCP and SCTP to transmit data between processes. It also utilizes the recovery facility of the underlying protocol (for example, TCP) to retransmit the lost data during the data propagation phase.

A stream socket created on TCP can be in different states, as shown by the diagram below. A brief description of the different flags used in the illustration below is as follows:

  • The SYN represents that the synchronization flag is set, while the number in front of SYN is the sequence number of the packet being sent.

  • The ACK represents that the acknowledgment flag is set, while the number in front of ACK is a sequence number indicating the last successfully received byte by the remote peer. TCP numbers each byte of the connection in each direction.

  • The FIN represents that the finish flag is set, while the number in front of FIN is a sequence number indicating the last successfully received byte by the remote peer.

The FIN represents that the finish flag is set, while the number in front of FIN is a sequence number indicating the last successfully received byte by the remote peer.

Data packets
Data packets
Retransmission
Retransmission
SYN = 10
SYN = 10
ACK = 11, SYN = 26
ACK = 11, SYN = 26
SYN_RCVD — Accepted connection request and sent acknowledgment with own SYN flag to synchronize both systems
SYN_RCVD — Accepted connection reque...
SYN_SENT — Sent a request to synchronize and establish a connection
SYN_SENT — Sent a request to synchr...
ESTABLISHED — Created connection by synchronizing to both the systems and sent own ACK flag with data packet.
ESTABLISHED — Created connection by...
ACK = 27, SYN = 11
ACK = 27, SYN = 11
ESTABLISHED — Exchanging information and recovering data that is lost during the network propagation 
ESTABLISHED — Exchanging informatio...
ACK = 101, FIN = 117
ACK = 101, FIN = 117
ACK = 118, FIN = 101
ACK = 118, FIN = 101
ACK = 102
ACK = 102
FIN_WAIT — Sent a request to terminate connection when finish processing. The connection is partially open to receive data. 
FIN_WAIT — Sent a request to termina...
TIME_WAIT — Received ACK flag against FIN flag and waiting for some time before closing connection.

CLOSED — Connection is closed completely.
TIME_WAIT — Received ACK flag agains...
LAST_ACK — Connection is closed completely after receiving acknowledgment
LAST_ACK — Connection is closed com...
ESTABLISHED — Got acknowledgement of system synchronization and received data packet.
ESTABLISHED — Got acknowledgement of...
ESTABLISHED — Exchanging information and recovering data that is lost during the network propagation 
ESTABLISHED — Exchanging information...
CLOSE_WAIT — The connection is partially open to send data. Sent FIN flag after data is sent completely.
CLOSE_WAIT — The connection is part...
Stream Socket 1Stream Socket 2
Establishing connection:
Establishing connection:
Socket state:
Socket state:
Color codes:
Color codes:
Data packets
Data packets
Data lost
Data lost
Data lost
Data lost
Connection established:
Connection established:
Connection teardown:
Connection teardown:
Viewer does not support full SVG 1.1
Creating a data stream between two connected devices

Note: "Stream Socket 2" in the figure above is a server socket, which we’ll introduce separately in the later section. Also, note that the notation for <flag> = <number> is just for writing convenience, while these values have separately defined locations in the TCP header.

For a TCP connection, if the sender doesn’t receive an acknowledgment of the sequence after a defined period, the data is considered lost, and a retransmission request is initiated. The initiator of the connection doesn’t necessarily have to close it. Any connected partner can request termination and enter a receive-only mode where it can receive but not send data on the channel. After the other party finishes sending, the connection is closed completely.

Datagram sockets#

Unlike stream sockets, datagram sockets don’t create an end-to-end channel between two endpoints to transfer data between processes. It just sends data and expects it to reach the receiver end. It’s used in scenarios where data loss is not significant. It usually operates on a UDP-like protocol for data transfer.

Receiving information
Receiving information
Sending information
Sending information
Data lost
Data lost
Data lost
Data lost
Datagram Socket 1Datagram Socket 2
Viewer does not support full SVG 1.1
Sending data over a datagram socket connection

Note: "Datagram Socket 2" in the figure above is a server socket, introduced later in this lesson.

Since the communication is stateless and doesn’t even contain packet sequence numbers, it’s nearly impossible to identify data lost during the propagation phase because there is no built-in mechanism in the UDP protocol to recover lost data. However, there are protocols that work on top of UDP and use application-level sequencing to make the communication reliable. While data flows in only one direction in the diagram above, the receiver can also send data in the other direction using the sender IP and port defined in the datagram socket.

Raw sockets

Raw sockets are another type of network socket that doesn’t specify any transport protocol. It’s used to directly access the protocol stack of a network suite, typically for testing or developing transport protocols.

The role of sockets in API development#

We can divide sockets into two main types based on their role in modern APIs.

  • Client: A process that requests or accesses information from another process or service through a communication channel.

  • Server: A process that provides a service or responds to a request from another process through a communication channel.

A typical client-server model is illustrated in the diagram below:

Server
Server
Client
socket()
socket()
connect()
connect()
socket()
socket()
bind()
bind()
listen()
listen()
accept()
accept()
recv()
recv()
send()
send()
close()
close()
send()
send()
recv()
recv()
close()
close()
The server socket goes back to listen for incoming requests
The server socket go...
The connection is established and handed over to a process thread
The connection is established a...
Viewer does not support full SVG 1.1
Client-server communication using a socket API

Server socket#

The server socket is configured to remain open and passively listen for incoming traffic by binding to a socket address. The server socket passively listens to incoming connection requests from clients and adds them to a connection queue. The server accepts the connections from the connection queue in a FIFO (first in, first out) manner and processes requests by creating separate process threads.

Client socket#

The client socket is created to get data or services from the server socket. The port and IP defined by the server socket must be known before a client socket can establish a connection with a server process. Typically, browsers automatically identify and populate well-known ports for commonly used services.

Network socket interface#

The socket API has different methods that can be used when communicating. The syntax of these methods may vary, and depend on the platform. Here, we only discuss these methods in general terms, without focusing on the syntax. A list of commonly used functions, along with brief descriptions, is given below.

Common Socket API Calls

Function

Description

socket()

Creates a file descriptor for an endpoint of a connection, representing the socket address family, socket type, transport protocol, and so on

bind()

Associates a buffer with the socket descriptor and gives it a unique local name

listen()

Changes the mode to only accept new connections and associates a connection queue to keep track of pending connections

connect()

Creates an active connection when using a stream socket and specifies the peer when using a datagram or raw socket

accept()

Connects to a pending request by defining a new socket descriptor with the same set of associated properties

send()

Writes data from the buffer to a socket and transmits it to the other end of a connection

recv()

Reads data from the socket and stores it in a buffer transmitted by the other end of a connection

close()

Closes the connection and frees the resources associated with the socket descriptor

Example of a running application#

A screenshot of network statistics taken from a running MEVN-stack application is given below. Before we start interpreting the facts, let’s understand the columns we want to focus on:

  • Proto: Shows the type of protocol used for network transport.

  • Local Address: Shows the address of the source socket.

  • Foreign Address: Shows the address of the destination socket.

  • State: Shows the state of the connection.

The four columns above are labeled as 1, 2, 3, and 4 in the illustration below.

Network statistics of a MEVN-stack application
Network statistics of a MEVN-stack application

In the first box, each socket uses TCP, which means that each socket creates a reliable communication channel. The socket addresses for the different services are displayed in the `Local Address` column in the second box. We can see that some rows have the IP address, 0.0.0.0, which means that the socket is open for connections through all device network interfaces.

In the fourth box, we can see the status of each row as follows:

  • LISTEN: Indicates that these are server sockets passively listening for incoming connection requests.

  • ESTABLISHED: Represents the connection between the Vue.js application, the Mongoose database, and the Node.js server.

  • TIME_WAIT: Shows that the connection is closed from the local socket and is waiting for the remote socket to finish sending data.

Summary#

We can conclude from this lesson that we have many abstraction layers to help developers develop portable applications without worrying about network details. The network sockets are one of the basic abstractions, the only interface responsible for creating connections at a core level.

In our API designs, we’ll only discuss concepts at a higher-level of abstraction instead of basic concepts like network sockets. Because all higher-level communication abstractions are based on sockets, we now understand how communication happens.

Quiz#

Match the information in the two columns below by selecting the correct option.

Match The Answer
Select an option from the left-hand side

A stream socket is

a pair of sockets containing information about the sender and the receiver

An API endpoint is specified by

3-tuples of information containing IP, port, and transport protocol

A connection is established by

a combination of an IP address and the port number


Latency and Throughput

World Wide Web